#include <iostream>
#include <exception>
#include <cstddef>

#define N 10000

extern void causes_an_exception();
extern void phase_1();
extern void phase_2();

void example() {
    std::exception* ex = nullptr;

    #pragma omp parallel shared(ex)
    {
        #pragma omp for
        for(int i = 0; i < N; i++) {
            try {
                causes_an_exception();
            }
            catch(std::exception& e) {
                #pragma omp atomic write
                ex = &e;
                #pragma omp cancel for
            }
        }
        
        // if an exception has been raised, cancel parallel region
        if(ex) { 
            #pragma omp cancel parallel 
        }
        
        phase_1();
        #pragma omp barrier
        phase_2();
    }
    
    // continue here if an exception has been thrown in the worksharing loop
    if(ex) {
        // handle exception stored in ex
    }
}